# _*_ coding:utf-8 _*_
# 开发团队: Mavericks
# 开发人员：Maverick·Ming
# 开发IDE： PyCharm
#   项目名：HelloWorld
#   文件名：6.10 继承_super.py
# 开发时间：2021/3/26 14:25

# 定义一个类Animal
#   这个类需要一个属性name, 两个方法run()，sleep()
class Animal:

    # 父类初始化方法
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name

    def run(self):
        print("I'm running")

    def sleep(self):
        print("I'm running")


# 定义一个狗类，age， bark()
# 父类Animal中所有方法都会被继承，包括特殊方法init
class Dog(Animal):

    # 当子类Dog有比Animal多的特有属性时，也需要重写初始化方法
    def __init__(self, name, age):
        # Animal.__init__(self, name) # 这样写无法预防父类变更之后需要修改对象的麻烦
        super().__init__(name)  # 通过super()返回的对象调用父类，不需要传递self
        # self._name = name  # 如果没有调用父类的init就要写，调用了就不用写
        self._age = age

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, age):
        self._age = age

    # 重写/覆盖 父类方法
    def run(self):
        print("Dog: I'm running")

    def bark(self):
        print("I'm braking!")


# d = Dog()  # 父类无init()时
# 如果父类有init方法，则不可以再直接 d = Dog() 创建对象，因为没有传参name
d = Dog('小黑', 18)  # 父类有init() name时
d.name = '小小黑'
# print(a.name) # NameError: name 'a' is not defined,方法可以继承，但是父类的name没有在子类中初始化

# 为了直接调用父类的init对父类已有的属性初始化可以直接在子类的init中添加以下代码
# Animal.__init__(self, name)

# 优点：不用考虑继承的属性，由父类的init初始化其属性，子类自己初始化自己的属性即可
# 缺点：如果父类变了，需要更改Animal为其他，则需要修改类，破坏了OCP原则，增加了代码间的耦合性
# 所以不建议这样对父类属性初始化

# super() 获取当前类的父类
